package com.jy.appmarket.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import android.os.Handler;

public class Command extends Thread {
	// private static final String TAG = "Command";
	private static Handler sHandler = new Handler();

	public interface CommandListener {
		void onCommandDone(int exitCode, ArrayList<String> output);
	}

	private String mCommand;
	private CommandListener mListener;

	private boolean mExecuting = false;
	private boolean mStop = false;

	public Command(String cmd) {
		mCommand = cmd;
	}

	public void setListener(CommandListener listener) {
		mListener = listener;
	}

	public boolean isExecuting() {
		return mExecuting;
	}

	public void stopCommand() {
		mStop = true;
	}

	@Override
	public void run() {
		mExecuting = true;
		mStop = false;
		ArrayList<String> stdOutput = new ArrayList<String>();
		ArrayList<String> errOutput = new ArrayList<String>();
		int exitCode = -999;
		try {
			Process process = Runtime.getRuntime().exec(mCommand);
			exitCode = grabProcessOutput(process, stdOutput, errOutput);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		mExecuting = false;
		if (mStop) {
			return;
		}
		final ArrayList<String> output = new ArrayList<String>();
		output.addAll(stdOutput);
		output.addAll(errOutput);

		final int code = exitCode;
		if (mListener != null) {
			sHandler.post(new Runnable() {
				@Override
				public void run() {
					mListener.onCommandDone(code, output);
				}
			});
		}
	}

	private static int grabProcessOutput(final Process process, final ArrayList<String> stdOutput,
			final ArrayList<String> errorOutput) throws InterruptedException {

		assert errorOutput != null;
		assert stdOutput != null;
		Thread t1 = new Thread("t1") {
			@Override
			public void run() {
				InputStreamReader is = new InputStreamReader(process.getErrorStream());
				BufferedReader errReader = new BufferedReader(is);

				try {
					while (true) {
						String line = errReader.readLine();
						if (line != null) {
							errorOutput.add(line);
						} else {
							break;
						}
					}
				} catch (IOException e) {
					e.printStackTrace();
					// do nothing.
				}
			}
		};

		Thread t2 = new Thread("t2") {
			@Override
			public void run() {
				InputStreamReader is = new InputStreamReader(process.getInputStream());
				BufferedReader outReader = new BufferedReader(is);

				try {
					while (true) {
						String line = outReader.readLine();
						if (line != null) {
							stdOutput.add(line);
						} else {
							break;
						}
					}
				} catch (IOException e) {
					e.printStackTrace();
					// do nothing.
				}
			}
		};

		t1.start();
		t2.start();

		try {
			t1.join();
			t2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return process.waitFor();
	}

}